#ifndef __GAME_STRING_H__
#define __GAME_STRING_H__

#include "game_def.h"

#include <string>
#include <sstream>
#include <stdarg.h>
#include <cstring>
#include <memory>
#include <vector>

#define C_VSNPRINTF_BUFFER_LENGTH   512

std::string __string_format(const char* format, ...);
BOOL __string_startwith(const std::string& src,const char* val);
BOOL __string_startwith(const std::string& src,std::string& val);
BOOL __string_endwith(const std::string src, const std::string val);
BOOL __string_endwith(const std::string src, const char* val);
BOOL __is_empty_string(const char* v);
std::vector<std::string> __string_split(const std::string& string, const std::string& delim);
std::string __string_join(const std::vector<std::string>& vec,const std::string& delim);
void __string_to_lower_case(std::string &str);
void __string_to_upper_case(std::string &str);
// 移除首尾空格
void __string_trim(char *str);
void __string_trim(std::string &str);

class CGameValue
{
  std::string _str;

public:
  /**
   *@brief 值对象构造
   */
  CGameValue(const CHAR *ptr, size_t nRow = 0, CHAR splittr = ',')
  {
    if (ptr)
    {
      _str = ptr;
    }

    size_t start_i = 0;
    size_t end_i = _str.find_first_of(splittr);

    for (size_t i = 0; i < nRow; i++)
    {
      if (end_i < _str.size())
      {
        start_i = end_i + 1;
      }
      else
        start_i = end_i;

      end_i = _str.find_first_of(splittr, start_i);
    }

    if (start_i < _str.size())
    {
      if (end_i < _str.size())
        _str = _str.substr(start_i, end_i - start_i);
      else
        _str = _str.substr(start_i);
    }
    else
      _str.clear();

    // 去掉包围的""
    if (_str.size() > 2 && _str.c_str()[0] == '\"' && _str.c_str()[_str.size() - 1] == '\"')
    {
      _str = _str.substr(1, _str.size() - 2);
    }
  }

  /**
   *@brief 值对象构造
   */
  CGameValue(const std::string &str, size_t nRow = 0, CHAR splitter = ',')
  {
    *this = CGameValue(str.c_str(), nRow, splitter);
  }

  /**
   *@brief 值对象构造
   */
  CGameValue(const CGameValue &v)
  {
    _str = v._str;
  }

  /**
   *@brief 获取值
   */
  std::string substr(const CHAR *ptr, size_t nRow = 0, CHAR splitter = ',') const
  {
    return CGameValue(_str, nRow, splitter)._str;
  }

  /**
   *@brief 作为char返回值
   */
  const CHAR *c_str() const
  {
    return _str.c_str();
  }

  /**
   *@brief 作为signed CHAR返回值
   */
  operator INT8() const
  {
    return _String2Value<INT8>(_str.c_str());
  }

  /**
   *@brief 作为unsigned CHAR返回值
   */
  operator UINT8() const
  {
    return _String2Value<UINT8>(_str.c_str());
  }

  /**
   *@brief 作为SHORT返回值
   */
  operator INT16() const
  {
    return _String2Value<INT16>(_str.c_str());
  }

  /**
   *@brief 作为unsigned SHORT返回值
   */
  operator UINT16() const
  {
    return _String2Value<UINT16>(_str.c_str());
  }

  /**
   *@brief 作为int返回值
   */
  operator INT32() const
  {
    return _String2Value<INT32>(_str.c_str());
  }

  /**
   *@brief 作为unsigned int返回值
   */
  operator UINT32() const
  {
    return _String2Value<UINT32>(_str.c_str());
  }

  /**
   *@brief 作为unsigned int返回值
   */
  operator UINT64() const
  {
    return _String2Value<UINT64>(_str.c_str());
  }

  /**
   *@brief 作为float返回值
   */
  operator FLOAT() const
  {
    return (FLOAT)atof(_str.c_str());
  }

  /**
   *@brief 作为double返回值
   */
  operator double() const
  {
    return atof(_str.c_str());
  }

public:
  template <typename T>
  static T _String2Value(const CHAR *pStr,size_t len){
    T Result(0);

    if (!memcmp(pStr, "0x", 2) || !memcmp(pStr, "0X", 2))
    {
      // 16进制转换，暂时没使用；
      // size_t len = strlen(pStr);
    }
    else
    {
      // size_t len = strlen(pStr);
      BOOL isNegative = FALSE;

      for (size_t i = 0; i < len; i++)
      {
        if (pStr[i] >= '0' && pStr[i] <= '9')
        {
          Result = (Result * 10) + pStr[i] - '0';
        }
        else if (pStr[i] == '-')
        {
          if (Result)
          {
            break;
          }

          isNegative = TRUE;
        }
        else if (pStr[i] == 32 || pStr[i] == 10 || pStr[i] == 9)
        {
          if (Result)
          {
            break;
          }
        }
        else
        {
          break;
        }
      }

      if (isNegative)
      {
        Result = -Result;
      }
    }

    return Result;
  }

  template <typename T>
  static T _String2Value(const CHAR *pStr)
  {
    size_t len = strlen(pStr);
    return _String2Value<T>(pStr,len);
  }
};

#endif
